-- set search_path to sm_sc;
-- drop function if exists sm_sc.fv_opr_pool_max_stride_1(anyarray, int[]);
create or replace function sm_sc.fv_opr_pool_max_stride_1
(
  i_background              anyarray                                             ,
  i_window_len              int[]           -- 窗口
)
returns anyarray
as
$$
-- declare 
begin
  -- 审计
  if current_setting('pg4ml._v_is_debug_check', true) = '1'
  then
    -- 审计二维长度
    if array_ndims(i_background) > 4 or array_ndims(i_window_len) > 1
    then 
      raise exception 'no method for such i_background or i_window_len ndims!';
    elsif array_length(i_window_len, 1) > 2 and array_length(i_window_len, 1) <> array_ndims(i_background)
    then 
      raise exception 'no method for such i_window length!  Dims: %;', array_dims(i_window_len);
    elsif array_length(i_window_len, 1) = 3 and i_window_len[1] <> array_length(i_background, 1)
      or array_length(i_window_len, 1) = 4 and (i_window_len[1] <> array_length(i_background, 1) or i_window_len[2] <> array_length(i_background, 2))
    then 
      raise exception 'unmatch length between i_window and i_background at 3d or 4d.';
    end if;
  end if;
  
  if array_ndims(i_background) = 1 and array_length(i_window_len, 1) = 1
  then 
    if array_length(i_background, 1) < i_window_len[1]
    then 
      raise exception 'imperfect window at 1d.';
    else 
      return 
      (
        select 
          array_agg
          (
            sm_sc.fv_aggr_slice_max
            (
              i_background[col_a_y : col_a_y + i_window_len[1] - 1] 
            )
            order by col_a_y
          )
        from generate_series(1, array_length(i_background, 1) - i_window_len[1] + 1) tb_a_y(col_a_y)
      )
      ;
    end if;
  end if;
  
  if array_length(i_background, array_ndims(i_background) - 1) < i_window_len[1]
  then 
    raise exception 'imperfect window at 1d.';
  elsif array_length(i_background, array_ndims(i_background)) < i_window_len[2]
  then 
    raise exception 'imperfect window at 2d.';
  else
    return 
      sm_sc.fv_pool_max
      (
        i_background     , 
        i_window_len
      )
    ;
  end if;
end
$$
language plpgsql stable
parallel safe
cost 100;
-- -- set search_path to sm_sc;
-- select sm_sc.fv_opr_pool_max_stride_1
--   (
--     array
--        [
--           [1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0, 9.0]
--         , [10.0,20.0,30.0,40.0,50.0,60.0,70.0, 8.0, 9.0]
--         , [100.0,200.0,300.0,400.0,500.0,600.0,700.0, 8.0, 9.0]
--         , [-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         ]
--    , array[3, 3]
--   );
-- select sm_sc.fv_opr_pool_max_stride_1
--   (
--     array
--       [
--         [
--           [1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0, 9.0]
--         , [10.0,20.0,30.0,40.0,50.0,60.0,70.0, 8.0, 9.0]
--         , [100.0,200.0,300.0,400.0,500.0,600.0,700.0, 8.0, 9.0]
--         , [-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         ]
--       , [
--           [1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0, 9.0]
--         , [10.0,20.0,30.0,40.0,50.0,60.0,70.0, 8.0, 9.0]
--         , [100.0,200.0,300.0,400.0,500.0,600.0,700.0, 8.0, 9.0]
--         , [-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         ]
--       ]
--    , array[3, 3]
--   );
-- select sm_sc.fv_opr_pool_max_stride_1
--   (
--     array
--     [
--       [
--         [
--           [1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0, 9.0]
--         , [10.0,20.0,30.0,40.0,50.0,60.0,70.0, 8.0, 9.0]
--         , [100.0,200.0,300.0,400.0,500.0,600.0,700.0, 8.0, 9.0]
--         , [-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         ]
--       , [
--           [1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0, 9.0]
--         , [10.0,20.0,30.0,40.0,50.0,60.0,70.0, 8.0, 9.0]
--         , [100.0,200.0,300.0,400.0,500.0,600.0,700.0, 8.0, 9.0]
--         , [-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         ]
--       ]
--     , [
--         [
--           [1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0, 9.0]
--         , [10.0,20.0,30.0,40.0,50.0,60.0,70.0, 8.0, 9.0]
--         , [100.0,200.0,300.0,400.0,500.0,600.0,700.0, 8.0, 9.0]
--         , [-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         ]
--       , [
--           [1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0, 9.0]
--         , [10.0,20.0,30.0,40.0,50.0,60.0,70.0, 8.0, 9.0]
--         , [100.0,200.0,300.0,400.0,500.0,600.0,700.0, 8.0, 9.0]
--         , [-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         ]
--       ]
--     ]
--   , array[3, 3]
--   );
-- select sm_sc.fv_opr_pool_max_stride_1
--   (
--     array
--        [
--           [1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0, 9.0]
--         , [10.0,20.0,30.0,40.0,50.0,60.0,70.0, 8.0, 9.0]
--         , [100.0,200.0,300.0,400.0,500.0,600.0,700.0, 8.0, 9.0]
--         , [-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         , [-10.0,-20.0,-30.0,-40.0,-50.0,-60.0,-70.0, 8.0, 9.0]
--         ]
--    , array[3, 3]
--   );

-- select sm_sc.fv_opr_pool_max_stride_1
--   (
--     array[1, 2, 3, 4, 5, 6, 7, 8, 9]
--     , array[3]
--   );